Step 1 (PR-H): Add grails-jacoco convention plugin + Codecov coverage (depends on PR-G)#15687
Step 1 (PR-H): Add grails-jacoco convention plugin + Codecov coverage (depends on PR-G)#15687jamesfredley wants to merge 15 commits into
Conversation
Adds a grails-jacoco convention plugin that configures JaCoCo per subproject and registers a root jacocoAggregateReport task producing a single XML report for Codecov, handling the hibernate5/hibernate7 duplicate-class case. Applies grails-jacoco to 96 subprojects and adds the Coverage workflow that uploads to the existing codecov.yml configuration. Layers on top of PR-G (grails-code-analysis / grails-violation-aggregation), which provides the build-logic test infrastructure and plugin registration scaffold. Folds in the standalone coverage work from #15668. Extracted from the Hibernate 7 staging branch (PR #15654) per review feedback that JaCoCo should be introduced as its own focused PR for the project to review independently. Assisted-by: claude-code:claude-4.7-opus
There was a problem hiding this comment.
Pull request overview
This PR introduces a grails-jacoco Gradle convention plugin and corresponding GitHub Actions workflow to enable code coverage reporting and Codecov uploads. It's carved out from a larger Hibernate 7 work stream, depends on PR-G (grails-code-analysis), and is intended to be re-targeted at 8.0.x after that PR merges.
Changes:
- New
GrailsJacocoPluginbuild-logic convention plugin (with TestKit specs) that configures per-project JaCoCo and lazily registers a rootjacocoAggregateReporttask, excludinghibernate7source/class dirs to avoid duplicate-class errors while still aggregating their exec data. - Applies the new plugin alongside
grails-code-styleandgrails-code-analysisin ~84 subprojectbuild.gradlefiles (single-line plugin additions). - Adds
.github/workflows/coverage.ymlrunningjacocoAggregateReportfor grails-core and the nested grails-gradle build across a 3-OS matrix, then uploads the artifacts to Codecov.
Reviewed changes
Copilot reviewed 100 out of 100 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
build-logic/plugins/build.gradle |
Registers the new grailsJacoco plugin id. |
build-logic/plugins/src/main/groovy/.../GrailsJacocoPlugin.groovy |
New convention plugin: applies JaCoCo, wires jacocoTestReport, contributes to root jacocoAggregateReport. |
build-logic/plugins/src/test/groovy/.../GrailsJacocoPluginSpec.groovy |
TestKit specs for per-project task registration, aggregate dependency wiring, and skip behavior. |
.github/workflows/coverage.yml |
New CI workflow running coverage on a 3-OS matrix for both core and grails-gradle, uploading to Codecov. |
~84 */build.gradle files |
Apply the grails-jacoco plugin alongside existing code-style/analysis plugins. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
The PR comments file appears to be empty (only the header row is present). I cannot analyze review discussions or suggestions without actual comment data. |
) Continues shrinking the PR-A review surface by reverting the portions of this branch split into standalone PRs against 8.0.x, matching the established B/C/D/E revert pattern. Once these land on 8.0.x and 8.0.x is merged back into this branch, the reverted changes return through the merge, so the final state of stage-hibernate7 is unchanged - only the diff visible on PR-A is reduced. Reverted content: grails-code-analysis convention plugin (PR #15686, PR-G) GrailsCodeAnalysisPlugin/Extension, GrailsViolationAggregationPlugin (+specs), the codeanalysis workflow, the pmd ruleset resource, the codenarcFix improvements and config relocation in GrailsCodeStylePlugin, spotbugs/pmd build deps, and the grails-code-analysis apply-line across all modules (incl. the h7 clones). grails-jacoco convention plugin (PR #15687, PR-H) GrailsJacocoPlugin (+spec), the coverage workflow, and the grails-jacoco apply-line across all modules (incl. the h7 clones). NOT reverted (intentionally kept): - The codenarc violation fixes (f18465a) - reverting would re-introduce style violations; they are plugin-independent. - All hibernate7 BOM/clone content (the actual PR-A work). Verified: ./gradlew help configures the root, grails-gradle, and grails-forge builds; :build-logic-root:build-logic:test passes. Assisted-by: claude-code:claude-4.7-opus
…co-plugin Assisted-by: claude-code:claude-4.8-opus
The jacoco coverage.yml workflow used floating action tags (checkout@v6, setup-java@v4, upload-artifact@v7.0.1, download-artifact@v7.0.0) and an outdated setup-gradle pin, which the ASF org policy rejects, causing the Coverage workflow to fail at startup. Pin every action to the ASF-approved commit SHAs used elsewhere in the repo (checkout v6.0.2, setup-java v5.2.0, setup-gradle v6.1.0 with cache-provider: basic, upload-artifact v7.0.1, download-artifact v8.0.1). Assisted-by: claude-code:claude-4.8-opus
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## feat/grails-code-analysis-plugin #15687 +/- ##
=====================================================================
Coverage ? 49.0160%
Complexity ? 16323
=====================================================================
Files ? 1998
Lines ? 93853
Branches ? 16352
=====================================================================
Hits ? 46003
Misses ? 40621
Partials ? 7229 🚀 New features to boost your workflow:
|
…' into feat/grails-jacoco-plugin
|
Converted to draft. This PR is stacked on #15686 (eat/grails-code-analysis-plugin) and inherits its code-analysis jobs. I merged the updated base in, so it now carries the PMD 7.25.0 fix and the report-only CI config. It shouldn't leave draft until the violation-scope decision on #15686 is resolved - see #15686 (comment) for the full breakdown (~5k PMD + 187 SpotBugs in Core alone). |
|
Deferred for now, see #15686 (comment) |
Fixed signature
borinquenkid
left a comment
There was a problem hiding this comment.
📊 Pull Request Review Summary
This is an excellent, high-impact addition to the build ecosystem. Introducing a unified grails-jacoco convention plugin establishes a consistent, localized footprint across the multi-project architecture while ensuring test execution results aggregate cleanly into a single target for accurate upstream Codecov coverage processing.
🛠️ Core Build & Logic Analysis
🔌 GrailsJacocoPlugin.groovy
- Idempotent Root Registration: Dynamically registering the
jacocoAggregateReporttask on therootProjectvia the subproject plugin application is a great approach. Checkingroot.tasks.names.contains(AGGREGATE_TASK_NAME)keeps the lifecycle safe and dynamic as subprojects configure. - Variant Class Deduplication: The exclusion filter on line 109 (
if (!project.path.contains('hibernate7'))) is crucial. Because the Hibernate 7 variant subprojects output identical class names to the primary Hibernate 5 modules, bailing out of source/class directory aggregation for H7 blocks the dreaded JaCoCoCan't add different class with same nameexception. - Execution Data Integrity: Crucially, even though H7 classes are excluded from the report metrics to prevent duplicates, line 99 still correctly captures their
.execdata output (project.fileTree(...)). This ensures coverage driven during the Hibernate 7 suite runs is accurately credited back to the primary class definitions.
🧪 Test Harness (GrailsJacocoPluginSpec.groovy)
- The integration coverage utilizing Gradle's
GradleRunneris solid. Testing both the configuration presence (jacocoTestReporttask matching) and the explicit multi-project task dependencies (:app-module:testin dry-runs) gives great baseline confidence that refactors won't break the aggregation behavior.
⚙️ CI Pipeline Configuration (coverage.yml)
- Open Source Cache Alignment: Explicitly pinning
cache-provider: basicinsidegradle/actions/setup-gradleis an excellent configuration choice. Utilizing the basic provider honors the core open-source lifecycle, avoiding the proprietary, commercial terms of use attached to the default enhanced provider in version 6+. - Partial Upload Resilience: Setting
if: always()on theupload-coveragejob guarantees that even if individual test suites or OS matrix blocks time out or experience independent tool failures, the coverage metrics captured up to that point are still packaged and piped over to Codecov.
💡 Architectural Recommendation / Improvement
Inside GrailsJacocoPlugin.groovy (lines 97–102), the execution data configuration is currently mapped via a dynamic task configuration block inside contributeToRootAggregateReport:
aggregateTask.configure { JacocoReport task ->
task.dependsOn project.tasks.withType(Test)
task.executionData.from(
project.fileTree(project.file('build/jacoco')) { include '*.exec' }
)
}The Opportunity: Since this plugin is meant to be applied globally across all code modules, we can harden this dependency wiring against unexpected build layout variations by hooking directly into the output providers of the individual Test tasks.
Instead of hardcoding a file tree string path search for build/jacoco/*.exec (which can occasionally experience evaluation timing race conditions if a submodule overrides its standard layout directory structure), you can bind directly to the task providers.
Updating that configuration block to leverage provider mapping safely maps execution dependencies lazily:
aggregateTask.configure { JacocoReport task ->
project.tasks.withType(Test).configureEach { Test testTask ->
task.dependsOn(testTask)
// Dynamically binds to the precise runtime execution data location of the test task instance
task.executionData.from(testTask.extensions.getByType(JacocoTaskExtension).destinationFile)
}
}…ted sources Co-Authored-By: Gemini <noreply@google.com>
- Restrict Spotless to target only production Java files - Configure Spotless importOrder and removeUnusedImports to match Checkstyle layout conventions - Remove google-java-format from Spotless configurations to avoid JDK 25 compiler crashes - Clean up obsolete task references in build configurations - Fix Java styling and imports across grails-forge production files to satisfy Checkstyle validation Co-authored-by: Gemini <noreply@google.com>
The bespoke Spotless config in grails-forge fought Checkstyle (static import position and the merged grails import group it cannot express) and gated checkstyleMain behind spotlessCheck, hiding pre-existing violations. Remove the Spotless application/config so grails-forge relies on Checkstyle + CodeNarc via the shared grails-code-style plugin, matching the root build. Fix the violations this surfaces (whitespace, import order, annotation-array indentation). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds a grails-jacoco convention plugin that configures JaCoCo per subproject and registers a root jacocoAggregateReport task producing a single XML report for Codecov, handling the hibernate5/hibernate7 duplicate-class case. Applies grails-jacoco to 96 subprojects and adds the Coverage workflow that uploads to the existing codecov.yml configuration. Layers on top of PR-G (grails-code-analysis / grails-violation-aggregation), which provides the build-logic test infrastructure and plugin registration scaffold. Folds in the standalone coverage work from #15668. Extracted from the Hibernate 7 staging branch (PR #15654) per review feedback that JaCoCo should be introduced as its own focused PR for the project to review independently. Assisted-by: claude-code:claude-4.7-opus
The jacoco coverage.yml workflow used floating action tags (checkout@v6, setup-java@v4, upload-artifact@v7.0.1, download-artifact@v7.0.0) and an outdated setup-gradle pin, which the ASF org policy rejects, causing the Coverage workflow to fail at startup. Pin every action to the ASF-approved commit SHAs used elsewhere in the repo (checkout v6.0.2, setup-java v5.2.0, setup-gradle v6.1.0 with cache-provider: basic, upload-artifact v7.0.1, download-artifact v8.0.1). Assisted-by: claude-code:claude-4.8-opus
…core into feat/grails-jacoco-plugin
✅ All tests passed ✅🏷️ Commit: cea9799 Learn more about TestLens at testlens.app. |
Step 1 (PR-H): grails-jacoco convention plugin + Codecov coverage
Carved out of the Hibernate 7 Step 1 PR (#15654) per review feedback from @matrei that JaCoCo should be introduced in its own focused PR for the project to review/decide on independently.
What this adds
grails-jacococonvention plugin: configures JaCoCo per subproject, wiresjacocoTestReportafter eachtest, and registers a rootjacocoAggregateReporttask that produces a single XML report for Codecov - handling the hibernate5/hibernate7 duplicate-class case (identical class names across the two variants).grails-jacocoto the same 96 subprojects asgrails-code-analysis.coverage.ymlworkflow that runsjacocoAggregateReportacross grails-core and grails-gradle and uploads to Codecov via the existingcodecov.yml.Notes
cd build-logic && ../gradlew :build-logic:test.Assisted-by: claude-code:claude-4.7-opus